/*
 * Copyright (c) 2010, okazoh_tk. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  - Neither the name of the copyright holder nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "MaskImageNode.h"

using namespace alkes;

MaskImageNode::MaskImageNode()
: image_(0)
, mask_image_(0)
, dest_(Point2D::ZERO)
, scale_(Vector2D::ONE)
, degrees_(0)
, origin_(Vector2D::HALF)
{
}

MaskImageNode::~MaskImageNode()
{
}

void MaskImageNode::setDest(const Point2D& dest)
{
    // set destination position.
    setProperty(dest_, dest);
}

void MaskImageNode::setImage(TextureResource* new_image)
{
    // set new image.
    setProperty(image_, new_image);
}

void MaskImageNode::setMaskImage(alkes::TextureResource* new_mask_image)
{
    // set new mask image.
    setProperty(mask_image_, new_mask_image);
}

void MaskImageNode::onRender(GraphicsContext& gc)
{
    Image image(resource_cast<ImageBuffer*>(image_));

    // null image, do nothing.
    if (!image)
        return ;

    Image mask_image(resource_cast<ImageBuffer*>(mask_image_));

    IRenderTarget2D* target = gc.getRenderTarget2D();
    bool restore_matrix = false;

    Rect image_rect(image.getRect());
    Rect dst_rect(image.getRect());

    dst_rect.x = dest_.x;
    dst_rect.y = dest_.y;

    setRotate(target, image_rect, restore_matrix);
    setScale(target, image_rect, restore_matrix);

    target->drawImage(image, image_rect, dst_rect, gc.getOpacity());

    if (restore_matrix)
        target->popMatrix();
}

void MaskImageNode::setRotate(IRenderTarget2D* target, const Rect& image_rect, bool& restore_matrix) const
{
    if (degrees_ == 0)
        return ;

    if (!restore_matrix)
    {
        restore_matrix = true;
        target->pushMatrix();
    }

    target->rotate(degrees_, UVector2D(image_rect.width * origin_.x, image_rect.height * origin_.y));
}

void MaskImageNode::setScale(IRenderTarget2D* target, const Rect& /*image_rect*/, bool& restore_matrix) const
{
    if (scale_ == Vector2D::ONE)
        return ;

    if (!restore_matrix)
    {
        restore_matrix = true;
        target->pushMatrix();
    }

    target->scale(scale_.x, scale_.y);
}

